package com.view.shatter

import android.app.Application
import android.content.Context
import android.content.Intent
import android.view.View
import androidx.annotation.IdRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner

/**
 * 程序入口
 */
class ShatterManager(private val lifecycleOwner: LifecycleOwner) : LifecycleEventObserver {

    private val shatters = mutableListOf<Shatter>()

    internal val cache = ShatterCache()

    companion object {
        //管理全局上下文
        lateinit var applicationContext: Context

        //初始化框架，接收上下文
        @JvmStatic
        fun init(application: Application) {
            applicationContext = application.applicationContext
        }
    }

    init {
        lifecycleOwner.lifecycle.removeObserver(this)
        //添加了生命周期的监听
        lifecycleOwner.lifecycle.addObserver(this)
    }


    //这里只对Destroy生命周期回调做了处理，自动处理页面对应的Shatter销毁逻辑
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        shatters.forEach { it.onStateChanged(source, event) }

        if (event == Lifecycle.Event.ON_START) {
            shatters.forEach { it.onStart() }

        } else if (event == Lifecycle.Event.ON_RESUME) {
            shatters.forEach { it.onResume() }

        } else if (event == Lifecycle.Event.ON_PAUSE) {
            shatters.forEach { it.onPause() }

        } else if (event == Lifecycle.Event.ON_STOP) {
            shatters.forEach { it.onStop() }

        } else if (event == Lifecycle.Event.ON_DESTROY) {

            shatters.forEach { it.onDestroy() }
            destroy()
            source.lifecycle.removeObserver(this)
        }
    }

    fun onNewIntent(intent: Intent?) {
        if (lifecycleOwner is FragmentActivity)
            shatters.forEach { it.onNewIntent(intent) }
    }

    fun onRestart() {
        if (lifecycleOwner is FragmentActivity)
            shatters.forEach { it.onRestart() }
    }

    fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        shatters.forEach { it.onActivityResult(requestCode, resultCode, data) }
    }

    fun enableOnBackPressed(): Boolean {
        return if (lifecycleOwner is FragmentActivity) {
            shatters.find { !it.enableOnBackPressed() } == null
        } else {
            true
        }
    }

    fun onHiddenChanged(isHidden: Boolean) {
        if (lifecycleOwner is Fragment)
            shatters.forEach { it.onHiddenChanged(isHidden) }
    }

    /**
     * 入口1 添加Shatter到指定ID的容器中，
     *
     * @param containViewId 指定添加容器的布局Id
     * @param shatter 待添加的子碎片对象
     * @param isAsync 是否以异步加载的方式加载布局
     * @param index 如果有多个布局添加，指定添加到容器中的索引位置
     *
     */
    fun addShatter(@IdRes containViewId: Int, shatter: Shatter, isAsync: Boolean = false, index: Int = -1) = apply {
        addShatter(containViewId, shatter, isAsync, index, null)
    }

    fun addShatter(@IdRes containViewId: Int, shatter: Shatter, isAsync: Boolean = false, index: Int = -1, callback: (() -> Unit)?) = apply {
        shatter.shatterManager = this
        val view: View? = when (lifecycleOwner) {
            is FragmentActivity -> lifecycleOwner.findViewById(containViewId)
            is Fragment -> lifecycleOwner.requireView().findViewById(containViewId)
            else -> null
        }
        addShatter(view, shatter, isAsync, index, callback)
    }

    /**
     * 入口2 添加Shatter到指定的容器中，
     *
     * @param containView 指定添加容器的ViewGroup对象
     * @param shatter 待添加的子碎片对象
     * @param isAsync 是否以异步加载的方式加载布局
     * @param index 如果有多个布局添加，指定添加到容器中的索引位置
     *
     */
    fun addShatter(containView: View?, shatter: Shatter, isAsync: Boolean = false, index: Int = -1) = apply {
        addShatter(containView, shatter, isAsync, index, null)
    }

    /**
     * 总入口
     */
    fun addShatter(containView: View?, shatter: Shatter, isAsync: Boolean = false, index: Int = -1, callback: (() -> Unit)?) = apply {
        shatter.shatterManager = this
        shatter.containView = containView
        shatter.attachToLifecycleOwner(lifecycleOwner, isAsync, index, callback)

        if (index == -1) {
            shatters.add(shatter)
        } else {
            shatters.add(index, shatter)
        }

        cache.putShatter(shatter)
    }

    //快速入口
    fun addShatter(@IdRes containViewId: Int, shatter: Shatter) = apply {
        addShatter(containViewId, shatter, false, -1, null)
    }

    fun addShatter(containView: View?, shatter: Shatter) = apply {
        addShatter(containView, shatter, false, -1, null)
    }

    fun addShatter(@IdRes containViewId: Int, shatter: Shatter, callback: (() -> Unit)?) = apply {
        addShatter(containViewId, shatter, false, -1, callback)
    }

    fun addShatter(containView: View?, shatter: Shatter, callback: (() -> Unit)?) = apply {
        addShatter(containView, shatter, false, -1, callback)
    }

    /**
     *入口3 添加非布局类型的Shatter
     *
     * 不需要设置布局的加载方式和索引
     */
    fun addShatter(shatter: Shatter) = apply {
        shatter.shatterManager = this
        shatter.attachToLifecycleOwner(lifecycleOwner, false, -1, null)

        shatters.add(shatter)
        cache.putShatter(shatter)
    }

    /**
     * 入口4 预加载Shatter对象和布局
     *
     */
    fun preloadShatter(shatter: Shatter, isAsync: Boolean = false, callback: (() -> Unit)?) {
        shatter.shatterManager = this
        shatter.preload(lifecycleOwner, isAsync, callback)
    }

    //移除指定的Shatter
    fun remove(shatter: Shatter) {
        shatter.onDestroy()
        cache.removeShatter(shatter.getTag())
        shatters.remove(shatter)
    }

    // 移除所有Shatter对象
    fun removeAllShatter() {
        shatters.forEach { it.onDestroy() }
        shatters.clear()
        cache.clear()
    }

    // 移除特定类型的所有Shatter对象
    fun <T : Shatter> removeAllShatter(clazz: Class<T>) {
        val shattersToRemove = shatters.filterIsInstance(clazz)
        shattersToRemove.forEach { it.onDestroy() }
        shattersToRemove.forEach { cache.removeShatter(it.getTag()) }
        shatters.removeAll(shattersToRemove)
    }

    //找到指定的Shatter
    fun <T : Shatter> findShatter(clazz: Class<T>): T? {
        val tag = clazz.simpleName
        val shatter = shatters.find { it.getTag() == tag } ?: return null
        return shatter as T
    }

    fun <T : Shatter> findAllShatter(clazz: Class<T>): List<T>? {
        return shatters.filterIsInstance(clazz)
    }

    //销毁全部的Shatter，清空全部缓存
    private fun destroy() {
        cache.clear()
        shatters.clear()
    }

    fun interface OnAsyncCallback {
        fun OnSuccess();
    }

}